package fr.oz.mobile.common.ui 
{
	import adobe.utils.CustomActions;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	/**
	 * Propriété de Drag/Drop pour les listes d'affichage
	 * @author Romain
	 */
	
	public class DragDropableList extends Sprite
	{
		
		/* EVT */
		static public const STOP_AND_GO_WIZARD : String = "stop_and_go_wizard";
		static public var DRAGABLE	:	Boolean = true;
		
		/* VAR */
		private var currentY: Number;
		private var offsetY	: Number;
		private var dy		: Number;
		
		private var tabPos 	: Array = [];
		private var rank 	: Number;
		
		private var diffY 	: Number;
				
		private var newY 	: Number;
		
		private var myTimer	: Timer;
		private var speed	: Number = 0;
		
		private var top 		: int = 0;
		private var maxScroll 	: int = 0;
		private var isFollowing : Boolean;
		private var _hasMoved	: Boolean = false;
		
		private var temoinY		: int;
		
		/* Drag Dropable List */
		public function DragDropableList() 
		{
			DRAGABLE = true;
			if (stage) init();
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/* Init */
		public  function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			addEventListener(Event.REMOVED_FROM_STAGE, kill);
			
			myTimer = new Timer(20, 0);
            myTimer.addEventListener(TimerEvent.TIMER, posSaver);
            myTimer.start();
			
			addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
			
			isFollowing = true;
		}
		
		/* Stop And Go Following */
		public function stopAndGo():void 
		{
			//removeEventListener(Event.ENTER_FRAME, handleMouseUpEnterFrame);
			
			isFollowing = false; 
			
		}
		
		/* Set Limits */
		public function setLimits ( topY : int, viewHeight:int, contentHeight : int) : void
		{
			top = topY;
			maxScroll = -(contentHeight - viewHeight - topY);
			
			//OzLogger.warn(low, top);
		}
		
		/* POS X SAVER */
		private function posSaver(e:Event):void 
		{
			//tf.text = "x: " + x + " y: " + y;
			tabPos.push( y  );

			
			if (tabPos.length > 1)	diffY = Number(tabPos[(tabPos.length -1)] - tabPos[(tabPos.length -2)]);
			else diffY = 0;
			
			// clean
			if (tabPos.length > 1000) tabPos = [];	
		}
		
		/* SMOOTH EXIT */
		private function handleMouseUpEnterFrame(e:Event):void 
		{
			// speed
			
			if (isFollowing)
			{
				//OzLogger.focus("Drag dropable list ::UP ENTERFRAME");
				
				dy 	= newY - y;
				y 	= int(newY - (dy * .8));
				
				// kill
				if ( y == newY ) removeEventListener(Event.ENTER_FRAME, handleMouseUpEnterFrame);
				
				// back
				//if ( (y > low) || (y < (top*-1)) )
				if ( (y > top) || (y < maxScroll) )
				{
					//OzLogger.warn(y);
					
					// D I S P O S E
					//if(myTimer)myTimer.stop();
					removeEventListener(Event.ENTER_FRAME, handleMouseUpEnterFrame);
		
				}
			}
		}
		
		
		/* MOUSE EVENTS */
		private function handleMouseUp(e:MouseEvent):void 
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
			removeEventListener(Event.ENTER_FRAME, handleMouseDownEnterframe);

			newY = y + (diffY * 8);
			
			addEventListener(Event.ENTER_FRAME, handleMouseUpEnterFrame);		
		}
		
		private function handleMouseDown(e:MouseEvent):void 
		{
			if(DRAGABLE){
				_hasMoved = false;
				temoinY = y;
				isFollowing = true;
				currentY = y;
				offsetY = parent.mouseY - y;
				speed = 0;
				addEventListener(Event.ENTER_FRAME, handleMouseDownEnterframe);
				stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
			}
		}
		
		
		private function handleMouseDownEnterframe(e:Event):void 
		{
			dy 	= parent.mouseY - offsetY;
			
			if (dy > top) {
				dy = top;// - speed;
			}
			else if (dy < maxScroll) {
				dy = maxScroll;// - speed;
			}
			else speed = speed * 0.5 + (dy - currentY) * .5;
			
			currentY += (dy - currentY) * 0.5;
			y = Math.round(currentY);
			
			/*var tempY : int = int(y + (dy - y) * 0.5);
			//OzLogger.log(tempY);
			
			if ( (tempY <= low) && (tempY >= (top*-1)) )
			{
				y = tempY;
				//OzLogger.focus(y);
			}*/
		}
		
		/* Remove */
		private function kill ( evt : Event ) : void
		{
			if(myTimer)myTimer.stop();
			removeEventListener(Event.ENTER_FRAME, handleMouseDownEnterframe);
			removeEventListener(Event.REMOVED_FROM_STAGE, kill);
			
			tabPos = null;
			myTimer = null;
			
		}
		
		public function get hasMoved():Boolean { 
			_hasMoved = (Math.abs(temoinY- y) > 5 ) ? true : false;
			return _hasMoved;
		}
		
		public function disable():void
		{
			removeEventListener(Event.ENTER_FRAME, handleMouseDownEnterframe);
			removeEventListener(Event.REMOVED_FROM_STAGE, kill);
			
			myTimer.removeEventListener(TimerEvent.TIMER, posSaver);
		}
		
	}
	
}